// @title           Admin模块API
// @version         1.0
// @description     This is a sample server celler server.
// @termsOfService  http://swagger.io/terms/

// @contact.name   API Support
// @contact.url    http://www.swagger.io/support
// @contact.email  sage12345678@qq.com

// @license.name  Apache 2.0
// @license.url   http://www.apache.org/licenses/LICENSE-2.0.html

// @host      localhost:8080
// @BasePath  /
// @schemes http https
// @produce      json,html

// @securityDefinitions.basic   BasicAuth

// @securityDefinitions.apikey	AdminKeyAuth
// @in							header
// @name						Authorization
// @description					管理站用Admin-Token, Header: Authorization
// @scope.write Grants write access

// @externalDocs.description  OpenAPI
// @externalDocs.url          https://swagger.io/resources/open-api/
package adminapp

import (
	"gitee.com/captials-team/ubdframe/src/apps"
	httpController "gitee.com/captials-team/ubdframe/src/apps/adminapp/controllers/http"
	"gitee.com/captials-team/ubdframe/src/common"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/domain/services"
	"gitee.com/captials-team/ubdframe/src/infrastructure/caches"
	mysqlDao "gitee.com/captials-team/ubdframe/src/infrastructure/dao/mysql"
	"gitee.com/captials-team/ubdframe/src/pkg/gin_http"
	v1log "gitee.com/captials-team/ubdframe/src/pkg/logs"
	"gitee.com/captials-team/ubdframe/src/pkg/uber_help"
	"go.uber.org/dig"
	"time"
)

type App struct {
	*apps.App

	l         v1log.ILog
	di        *dig.Scope
	ApiServer *ApiServer
}

func (app *App) initDao(conf *configstc.AdminAppConfig) {
	common.ErrPanic(app.di.Provide(func() (interfaces.ItfAdminDao, interfaces.ItfAdminLog) {
		var err error

		admin := mysqlDao.NewAdminDao(conf.DBConfig)
		adminLog := mysqlDao.NewAdminLogDao(conf.DBConfig)

		_, err = admin.Migrate()
		common.ErrPanic(err)

		_, err = adminLog.Migrate()
		common.ErrPanic(err)

		app.l.Info("migrate success")

		return admin, adminLog
	}))

	common.ErrPanic(app.di.Provide(func() (interfaces.ItfOrganize, interfaces.ItfOrganizeRelate) {
		var err error

		organizeDao := mysqlDao.NewOrganizeDao(conf.DBConfig)
		relateDao := mysqlDao.NewOrganizeRelateDao(conf.DBConfig)

		_, err = organizeDao.Migrate()
		common.ErrPanic(err)

		_, err = relateDao.Migrate()
		common.ErrPanic(err)

		app.l.Info("migrate success")

		return organizeDao, relateDao
	}))

	app.l.Info("provide dao success")

}

func (app *App) initCaches(conf *configstc.AdminAppConfig) {
	common.ErrPanic(app.di.Provide(func() caches.ItfCache {
		return caches.NewMemoryStore(time.Minute * 10)
	}), uber_help.ErrAlreadyProvided)

	app.l.Info("provide cache success")
}

func (app *App) initService() {
	common.ErrPanic(app.di.Provide(services.NewAdminService, dig.As(new(interfaces.ItfAdminService))))
	common.ErrPanic(app.di.Provide(services.NewOrganizeService, dig.As(new(interfaces.ItfOrganizeService))))

	app.l.Info("init service success")
}

func (app *App) initController() {
	common.ErrPanic(app.di.Provide(gin_http.NewCaptchaController, dig.As(new(interfaces.ItfCaptchaController))), uber_help.ErrAlreadyProvided)
	common.ErrPanic(app.di.Provide(httpController.NewAuthController, dig.As(new(interfaces.ItfAdminAuthController))), uber_help.ErrAlreadyProvided)
	common.ErrPanic(app.di.Provide(httpController.NewAdminController, dig.As(new(interfaces.ItfAdminManageController)), dig.As(new(interfaces.ItfAdminCenterController))), uber_help.ErrAlreadyProvided)
	common.ErrPanic(app.di.Provide(httpController.NewRbacController, dig.As(new(interfaces.ItfRbacManageController)), dig.As(new(interfaces.ItfAccreditController))), uber_help.ErrAlreadyProvided)
	common.ErrPanic(app.di.Provide(httpController.NewAdminLogController, dig.As(new(interfaces.ItfAdminLogController))), uber_help.ErrAlreadyProvided)
	common.ErrPanic(app.di.Provide(httpController.NewOrganizeManageController, dig.As(new(interfaces.ItfOrganizeManageController))), uber_help.ErrAlreadyProvided)
}

func NewApp(di *dig.Container, conf *configstc.AdminAppConfig, logger v1log.ILog) *App {
	scope := di.Scope("admin")

	common.ErrPanic(scope.Provide(func() *dig.Scope {
		return scope
	}), uber_help.ErrAlreadyProvided)
	common.ErrPanic(scope.Provide(func() *configstc.AdminAppConfig {
		return conf
	}), uber_help.ErrAlreadyProvided)

	app := &App{
		di:  scope,
		l:   logger,
		App: apps.NewApp(di, "admin_app"),
	}

	app.WithModule(conf.ModuleMode)

	//db初始化
	common.ErrPanic(scope.Invoke(app.initCaches))
	common.ErrPanic(scope.Invoke(app.initDao))
	common.ErrPanic(scope.Invoke(app.initService))
	common.ErrPanic(scope.Invoke(app.initController))

	if conf.ApiServer.Enable {
		common.ErrPanic(scope.Provide(NewApiServer))
		common.ErrPanic(scope.Invoke(func(api *ApiServer) {
			app.WithApiServer(api)
			app.ApiServer = api
		}))
	}

	return app
}
